# encoding: utf-8

"""
wwww http://www.baidu.com
"""

import sys
import re
import socket
import gzip


class InvalidHttpURL(BaseException):
    pass


class InvalidHttpResponse(BaseException):
    pass


HTTP_REGEX_PATTERN = "((?P<schema>[0-9a-zA-Z]+)://)?(?P<host>[a-zA-Z0-9\.]+)(:(?P<port>[0-9]+))?(?P<resource>(/([0-9a-zA-Z\%])?)*)(\?(?P<argument>.+))?"
HTTP_HEADER_TEMPLATE = "GET {} HTTP/1.1\r\n" + \
                       "Host: {}\r\n" + \
                       "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36\r\n" + \
                       "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3\r\n" + \
                       "Accept-Encoding: gzip, deflate\r\n" + \
                       "Accept-Language: en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7\r\n" + \
                       "Dnt: 1\r\n" + \
                       "Proxy-Connection: keep-alive\r\n" + \
                       "Upgrade-Insecure-Requests: 1\r\n" + \
                       "X-Lantern-Version: 5.4.7\r\n\r\n"

# 解析URL
def parse_url(url):
    m = re.match(HTTP_REGEX_PATTERN, url)
    if not m:
        raise InvalidHttpURL
    return m.groupdict()


# 连接到服务器
def connect_to_server(host, port):
    sock_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock_server.connect((host, port))
    return sock_server

# 解析HTTP响应头
def parse_http_header(header):
    header_info = header.split("\r\n".encode("utf-8"))
    headers = {}
    m = re.match("HTTP/1.1\\s+(?P<status_code>[0-9]+)\\s+(?P<reason>.+)".encode("utf-8"), header_info[0])
    if not m:
        raise InvalidHttpResponse(header_info[0])
    for h in header_info[1:]:
        header, value = re.split(":\\s+".encode("utf-8"), h)
        headers[header.decode("utf-8")] = value.decode("utf-8")

    return int(m.group("status_code")), headers

# 解压数据
def unzip_content(content):
    # import pdb
    # pdb.set_trace()
    return gzip.decompress(content)


def usage(app):
    print("usage: %s URL" % app)


try:
    url = sys.argv[1]
except:
    sys.stderr.write("[ ERROR ] Invalid arguments\n")
    usage(sys.argv[0])
else:
    url_info = parse_url(url)
    ip = socket.gethostbyname(url_info["host"])
    # 连接到远程服务器
    sock = connect_to_server(host=ip, port=(80 if url_info['port'] is None else int(url_info['port'])))
    http_header = HTTP_HEADER_TEMPLATE.format("/" if not url_info['resource'] else url_info['resource'],
                                              url_info['host'])
    # 发送HTTP请求
    sock.send(http_header.encode("utf-8"))

    # 接受HTTP响应
    response = sock.recv(65535)
    response_header, content = response.split("\r\n\r\n".encode("utf-8"))
    status_code, headers = parse_http_header(response_header)
    content_length = int(headers['Content-Length'])

    # print(content_length, len(content))
    if content_length != len(content):
        content += sock.recv(content_length - len(content))

    if "Content-Encoding" in headers and headers["Content-Encoding"] == "gzip":
        content = unzip_content(content)

    print(content)
    sock.close()
